package cn.com.headfree.evaluation.export;

import cn.com.headfree.base.controller.ResultData;
import cn.com.headfree.callback.call.FileServerCall;
import cn.com.headfree.entity.*;
import cn.com.headfree.evaluation.export.vo.EvaluationDeclareReportVo;
import cn.com.headfree.expert.export.policy.*;
import cn.com.headfree.expert.export.vo.SummaryData;
import cn.com.headfree.expert.export.vo.table.WorkInfoTable;
import cn.com.headfree.util.SysDictionaryUtil;
import cn.com.headfree.vo.*;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.TextRenderData;
import com.deepoove.poi.data.style.Style;
import com.deepoove.poi.data.style.TableStyle;
import feign.Response;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 导出word工具类
 */
@Service("evaluationDeclareExportWordService")
public class EvaluationDeclareExportWordService {

    private static final Logger log = LogManager.getLogger(EvaluationDeclareExportWordService.class);

    @Autowired
    private FileServerCall fileServerCall;

    /**
     * 在本地生成word文档
     * @param response
     * @param data              结果对象
     * @param filename            本地生成word名称
     */
    public void exportWord(HttpServletResponse response, EvaluationDeclareReportVo data, String filename , String erpNo){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM");
        FileOutputStream out=null;
        XWPFTemplate template = null;
        InputStream inputStream = null;
        File file = null;
        cn.com.headfree.expert.export.vo.SummaryData datas = new SummaryData();//数据封装
        //样式
        Style textStyle = new Style();
        TableStyle headStyle = new TableStyle();
        TableStyle rowStyle = new TableStyle();
        rowStyle.setAlign(STJc.Enum.forInt(2));
        textStyle.setFontFamily("仿宋_GB2312");
        textStyle.setFontSize(12);
        textStyle.setColor("000000");
        headStyle.setAlign(STJc.CENTER);

        TDeclareEvaluationInfo declareEvaluationInfo = data.getDeclareEvaluationInfo();

        if(declareEvaluationInfo!=null){
            datas.setYear(String.valueOf(declareEvaluationInfo.getYear()));
            datas.setMajor(null);
            String declareType="";
            String typenum = declareEvaluationInfo.getDeclareType();
            if("1".equals(typenum)){
                declareType="管理类";
            }else if("2".equals(typenum)){
                declareType="技术类";
            }else if("3".equals(typenum)){
                declareType="技能类";
            }
            datas.setCategory(declareType);
        }
        TEmpBaseInfo baseInfo = data.gettEmpBaseInfo();
        if(baseInfo != null){
            datas.setUnit(baseInfo.getUnit());
            datas.setName(baseInfo.getName());
            datas.setSex(SysDictionaryUtil.getNameByValueForDefault("Gender",baseInfo.getSex()));
            if(baseInfo.getBirthDate() != null){
                datas.setBirthDate(sdf1.format(baseInfo.getBirthDate()));
            }
            datas.setUnitDept(baseInfo.getDept());
            datas.setRealPost(baseInfo.getRealPost());
            datas.setMobilephone(baseInfo.getMobilePhone());
        }
        EducateInfoVo highEdus = data.getHighEdus();
        if(highEdus!=null){
            datas.setHighEduc(SysDictionaryUtil.getNameByValueForDefault("PersonnelQualifications", highEdus.getEducName()));
            datas.setHighdegree(SysDictionaryUtil.getNameByValueForDefault("AcademicDegree", highEdus.getDegreeName()));
            datas.setHighMajor(highEdus.getMajor());
            datas.setGradSchool(highEdus.getGradSchool());
        }

        //近三年绩效
        ThreeYearTable threeYearTable = new ThreeYearTable();
        List<YearEffectVo> yearEffectVos = data.getYearEffectVos();
        List<RowRenderData> yearRowList = new ArrayList<>();

        Calendar date = Calendar.getInstance();
        int currentYear = Integer.valueOf(date.get(Calendar.YEAR));
        int endYear = currentYear - 1;
        int middleYear = currentYear - 2;
        int startYear = currentYear - 3;
        Map<Integer,String> yearEffecMap = new HashMap<Integer,String>();
        yearEffectVos.forEach(item->{
            yearEffecMap.put(item.getYear(),item.getPerforGrade());
        });

        RowRenderData yearEffectrow1 = RowRenderData.build(
                new TextRenderData(startYear+"年年度绩效", textStyle),
                new TextRenderData(middleYear+"年年度绩效", textStyle),
                new TextRenderData(endYear+"年年度绩效", textStyle));
        yearEffectrow1.setRowStyle(rowStyle);
        RowRenderData yearEffectrow2 = RowRenderData.build(
                new TextRenderData(yearEffecMap.get(startYear), textStyle),
                new TextRenderData(yearEffecMap.get(middleYear), textStyle),
                new TextRenderData(yearEffecMap.get(endYear), textStyle));
        yearEffectrow2.setRowStyle(rowStyle);
        yearRowList.add(yearEffectrow2);
        yearRowList.add(yearEffectrow1);
        threeYearTable.setThreeYears(yearRowList);
        datas.setThreeYearTable(threeYearTable);


        //主要工作经历
        cn.com.headfree.expert.export.vo.table.WorkInfoTable workInfoTable = new cn.com.headfree.expert.export.vo.table.WorkInfoTable();
        List<WorkExpInfoVo> workExpInfoVos = data.getWorkExpInfoVos();
        List<RowRenderData> workInfoRowList = new ArrayList<>();
        if(workExpInfoVos != null && workExpInfoVos.size() > 0){
            for(int i=workExpInfoVos.size()-1;i>=0;i--){
                if(workExpInfoVos.get(i).getIsHide() == null || !(workExpInfoVos.get(i).getIsHide().equals("0"))) {
                    String startTime = "";
                    String endTime = "";
                    if (workExpInfoVos.get(i).getStartTime() != null) {
                        startTime = sdf.format(workExpInfoVos.get(i).getStartTime());
                    }
                    if (workExpInfoVos.get(i).getEndTime() != null) {
                        endTime = sdf.format(workExpInfoVos.get(i).getEndTime());
                    }
                    String workInfoStr = String.format("%s %s( %s %s)",
                            workExpInfoVos.get(i).getCompany()
                            ,workExpInfoVos.get(i).getDept()
                            ,workExpInfoVos.get(i).getPost()
                            ,workExpInfoVos.get(i).getJobContent());
                    workInfoStr = workInfoStr.replace("null","");
                    RowRenderData row = RowRenderData.build(
                            new TextRenderData(startTime+"-"+endTime, textStyle),
                            new TextRenderData(workInfoStr, textStyle));
                    row.setRowStyle(rowStyle);
                    workInfoRowList.add(row);
                }
            }
        }
        workInfoTable.setWorkInfos(workInfoRowList);
        datas.setWorkInfoTable(workInfoTable);

        //成果获奖;获奖时间 成果名称	奖项类别	奖项级别	奖项等级	授予单位	排序
        cn.com.headfree.expert.export.vo.table.WorkInfoTable tecManTable = new cn.com.headfree.expert.export.vo.table.WorkInfoTable();
        List<TTecManInnovVo> tecManInnovVos = data.getTecManInnovVos();
        List<RowRenderData> tecManRowList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(tecManInnovVos)){
            tecManInnovVos.forEach(item->{
                RowRenderData row = RowRenderData.build(
                        new TextRenderData(sdf.format(item.getAwardDate()), textStyle),
                        new TextRenderData(item.getAchiName(), textStyle),
                        new TextRenderData(item.getAchiTypeName(), textStyle),
                        new TextRenderData(item.getAwardLevelName(), textStyle),
                        new TextRenderData(item.getAwardGradeName(), textStyle),
                        new TextRenderData(item.getAwardOrg(), textStyle),
                        new TextRenderData(String.valueOf(item.getRank()), textStyle));
                row.setRowStyle(rowStyle);
                tecManRowList.add(row);
            });
        }
        tecManTable.setWorkInfos(tecManRowList);
        datas.setTecManTable(tecManTable);


        //授权专利;授予时间	专利名称	专利类型	专利号	排序
        cn.com.headfree.expert.export.vo.table.WorkInfoTable patentTable = new cn.com.headfree.expert.export.vo.table.WorkInfoTable();
        List<TPatentInfoVo> patentInfoVos = data.getPatentInfoVos();
        List<RowRenderData> patentRowList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(patentInfoVos)){
            patentInfoVos.forEach(item->{
                RowRenderData row = RowRenderData.build(
                        new TextRenderData(sdf.format(item.getApplyDate()), textStyle),
                        new TextRenderData(item.getPatentTypeName(), textStyle),
                        new TextRenderData(item.getPatentTypeName(), textStyle),
                        new TextRenderData(item.getPatentNo(), textStyle),
                        new TextRenderData(String.valueOf(item.getRank()), textStyle));
                row.setRowStyle(rowStyle);
                patentRowList.add(row);
            });
        }
        patentTable.setWorkInfos(patentRowList);
        datas.setPatentTable(patentTable);


        // 论文专著;发表时间	类别	论文专著名称	刊物名称	期刊号	收录情况	出版单位	排序
        cn.com.headfree.expert.export.vo.table.WorkInfoTable acadeTable = new cn.com.headfree.expert.export.vo.table.WorkInfoTable();
        List<TAcadeAchiveInfoVo> acadeAchiveVos = data.getAcadeAchiveVos();
        List<RowRenderData> acadeRowList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(acadeAchiveVos)){
            acadeAchiveVos.forEach(item->{
                RowRenderData row = RowRenderData.build(
                        new TextRenderData(sdf.format(item.getPubTime()), textStyle),
                        new TextRenderData(item.getAcadTypeName(), textStyle),
                        new TextRenderData(item.getAcadName(), textStyle),
                        new TextRenderData(item.getPubName(), textStyle),
                        new TextRenderData(item.getIssn(), textStyle),
                        new TextRenderData(item.getPeriodicNo(), textStyle),
                        new TextRenderData(item.getPublisher(), textStyle),
                        new TextRenderData(String.valueOf(item.getRank()), textStyle));
                row.setRowStyle(rowStyle);
                acadeRowList.add(row);
            });
        }
        acadeTable.setWorkInfos(acadeRowList);
        datas.setAcadeTable(acadeTable);

        //制度规范; 发布时间	标准、制度、规划或方案名称	发布单位	标准、制度、规划或方案级别	排序/角色
        cn.com.headfree.expert.export.vo.table.WorkInfoTable standTable = new cn.com.headfree.expert.export.vo.table.WorkInfoTable();
        List<TStandInfoVo> standInfoVos = data.getStandInfoVos();
        List<RowRenderData> standRowList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(standInfoVos)){
            standInfoVos.forEach(item->{
                RowRenderData row = RowRenderData.build(
                        new TextRenderData(sdf.format(item.getIssueTime()), textStyle),
                        new TextRenderData(item.getName(), textStyle),
                        new TextRenderData("", textStyle),
                        new TextRenderData(item.getLevelName(), textStyle),
                        new TextRenderData(String.valueOf(item.getRank()), textStyle));
                row.setRowStyle(rowStyle);
                standRowList.add(row);
            });
        }
        standTable.setWorkInfos(standRowList);
        datas.setStandTable(standTable);

        //个人荣誉;获得时间	荣誉名称	荣誉级别	授予单位
        cn.com.headfree.expert.export.vo.table.WorkInfoTable honorTable = new cn.com.headfree.expert.export.vo.table.WorkInfoTable();
        List<THonorInfo> honorDatasVos = data.getHonorDatasVos();
        List<RowRenderData> honorRowList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(honorDatasVos)){
            honorDatasVos.forEach(item->{
                RowRenderData row = RowRenderData.build(
                        new TextRenderData(sdf.format(item.getAcquTime()), textStyle),
                        new TextRenderData(item.getHonorTitle(), textStyle),
                        new TextRenderData(item.getHonorLevelName(), textStyle),
                        new TextRenderData(item.getAwardOrg(), textStyle));
                row.setRowStyle(rowStyle);
                honorRowList.add(row);
            });
        }
        honorTable.setWorkInfos(honorRowList);
        datas.setHonorTable(honorTable);


        //人才培养;课程（项目）名称	学时	参与人数（项目内容）	主办单位
        cn.com.headfree.expert.export.vo.table.WorkInfoTable perTrainTable = new cn.com.headfree.expert.export.vo.table.WorkInfoTable();
        List<TContiStudyInfo> studyAndTrainVos = data.getStudyAndTrainVos();
        List<RowRenderData> perTrainRowList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(studyAndTrainVos)){
            studyAndTrainVos.forEach(item->{
                RowRenderData row = RowRenderData.build(
                        new TextRenderData(item.getMajor(), textStyle),
                        new TextRenderData(String.valueOf(item.getStudyLength()), textStyle),
                        new TextRenderData("", textStyle),
                        new TextRenderData(item.getStudyPlace(), textStyle));
                row.setRowStyle(rowStyle);
                perTrainRowList.add(row);
            });
        }
        perTrainTable.setWorkInfos(perTrainRowList);
        datas.setPerTrainTable(perTrainTable);


        //技术规范;发文时间	名称	类别	内容摘要
        cn.com.headfree.expert.export.vo.table.WorkInfoTable tecStandardTable = new WorkInfoTable();
        List<TTecStandardInfo> tecStandardInfoVos = data.getTecStandardInfoVos();
        List<RowRenderData> tecStandardRowList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(tecStandardInfoVos)){
            tecStandardInfoVos.forEach(item->{
                RowRenderData row = RowRenderData.build(
                        new TextRenderData(sdf.format(item.getPostTime()), textStyle),
                        new TextRenderData(item.getStandardName(), textStyle),
                        new TextRenderData(item.getStandardTypeStr(), textStyle),
                        new TextRenderData(item.getSummary(), textStyle));
                row.setRowStyle(rowStyle);
                tecStandardRowList.add(row);
            });
        }
        tecStandardTable.setWorkInfos(tecStandardRowList);
        datas.setTecStandardTable(tecStandardTable);


        try {
            //获取头像
            TouXiangVo iamges = getTouXiang(erpNo);
            if(iamges != null && iamges.getInputStream()!=null){
                datas.setPic(new PictureRenderData(100, 160,".jpg",
                        iamges.getInputStream()));
            }
            ClassPathResource resource = new ClassPathResource("/templates/expert_declare_evalution_report.docx");
            inputStream = resource.getInputStream();
            Configure config = Configure.newBuilder().bind("three_year_table", new ThreeYearExpertPolicy())
                    .bind("work_info_table", new WorkStatusTablePolicy())
                    .bind("tec_man_table",new TecManTablePolicy())
                    .bind("patent_table",new PatentPolicy())
                    .bind("acade_table",new AcadePolicy())
                    .bind("stand_table",new StandPolicy())
                    .bind("honor_table",new HonorPolicy())
                    .bind("per_train_table",new PerTrainPolicy())
                    .bind("tec_standard_table",new TecStandardPolicy())
                    .build();
            template = XWPFTemplate.compile(inputStream,config).render(datas);
            String tempfilePath= UUID.randomUUID() +".docx";
            out = new FileOutputStream(tempfilePath);
            template.write(out);
            out.flush();
            responseWord(response,tempfilePath,filename);
            //删除临时文件
            file = new File(tempfilePath);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (out!=null){
                    out.close();
                }
                if (template!=null){
                    template.close();
                }
                if (file != null) {// 删除临时文件
                    if(file.exists()){
                        file.delete();
                    }
                }
            }catch (Exception e){
                log.error("关闭异常",e);
            }
        }
    }

    static SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMddHHmmss");

    private void responseWord(HttpServletResponse response,String path,String filename){
        File file = null;
        InputStream in = null;
        ServletOutputStream out = null;
        try{
            String downloadFileName=filename+simpleDateFormat.format(new Date())+".docx";
            file = new File(path);
            in = new FileInputStream(file);
            response.setCharacterEncoding("utf-8");
            response.setHeader("Cache-Control", "");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(downloadFileName, "UTF-8"))));
            out = response.getOutputStream();
            byte[] buffer = new byte[512];
            int bytesToRead = -1;
            // 用响应对象response中的输出流读取生成好的文件
            while ((bytesToRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
            out.flush();
        }catch (Exception ex){
            log.error("product word fail..",ex);
        }finally {
            if (in != null) {
                try {
                    in.close();
                    if (out != null) {
                        out.close();
                    }
                } catch (IOException e) {
                    log.error("删除删除临时文件出错:" + e);
                }
            }
        }
    }

    /**
     * 获取头像
     * @param erpNo
     * @return
     */
    public TouXiangVo getTouXiang(String erpNo){
        TouXiangVo touXiangVo = null;
        InputStream inputStream = null;
        String fileId=null;
        String name=null;
        //通过ERP号查询头像Id
        ResultData resultData = fileServerCall.findFileList("personManage",erpNo,"userHead");
        JSONArray jsonArray =null;
        JSONObject obj =null;
        if(null != resultData) {
            log.info("获取头像数据为--"+resultData.toString());
            if(null != resultData.getData()) {
                jsonArray = JSONArray.fromObject(resultData.getData());
                if((null != jsonArray)&&(0 < jsonArray.size())) {
                    for(int i=0;i<jsonArray.size();i++) {
                        obj = (JSONObject) jsonArray.get(i);
                        if(null != obj) {
                            fileId = obj.getString("id");
                            name = obj.getString("oldFileName");
                        }
                    }
                }
            }
        }
        //下载文件
        if(fileId != null){
            try {
                Response response = fileServerCall.downloadFile(fileId);

                //判断是否下载成功
                if(response.status()==200) {
                    Response.Body body = response.body();
                    inputStream = body.asInputStream();
//                    inputStream = new FileInputStream(new File("test_one.png"));
                    touXiangVo = new TouXiangVo();
                    touXiangVo.setName(name);
                    touXiangVo.setInputStream(inputStream);
                }

            }catch (Exception e){
                log.error("下载文件失败！", e);
            }

        }

        return touXiangVo;
    }
}
